package com.reconcile.phone.common.utils;

/**
 * 功能描述:
 *
 * @author zxl
 * @since 2024/2/21
 */
import java.math.BigDecimal;
import java.math.RoundingMode;

public class DistanceUtils {

  // 地球半径，单位：米
  private static final BigDecimal EARTH_RADIUS = new BigDecimal("6371000");

  private DistanceUtils() {
    // 私有构造函数，防止实例化
  }

  /**
   * 使用Haversine公式计算两个地球坐标点之间的距离。
   *
   * @param lat1Str 第一个点的纬度字符串
   * @param lon1Str 第一个点的经度字符串
   * @param lat2Str 第二个点的纬度字符串
   * @param lon2Str 第二个点的经度字符串
   * @return 以千米为单位的距离，精确到小数点后两位
   */
  public static BigDecimal calculateDistance(String lat1Str, String lon1Str, String lat2Str, String lon2Str) {
    // 将经纬度字符串转换为 BigDecimal 类型
    BigDecimal lat1 = new BigDecimal(lat1Str);
    BigDecimal lon1 = new BigDecimal(lon1Str);
    BigDecimal lat2 = new BigDecimal(lat2Str);
    BigDecimal lon2 = new BigDecimal(lon2Str);

    // 将经纬度转换为弧度
    BigDecimal dLat = lat2.subtract(lat1).multiply(BigDecimal.valueOf(Math.PI / 180));
    BigDecimal dLon = lon2.subtract(lon1).multiply(BigDecimal.valueOf(Math.PI / 180));

    // Haversine公式计算距离
    BigDecimal a = new BigDecimal(Math.sin(dLat.doubleValue() / 2) * Math.sin(dLat.doubleValue() / 2) +
        Math.cos(lat1.multiply(BigDecimal.valueOf(Math.PI / 180)).doubleValue()) *
            Math.cos(lat2.multiply(BigDecimal.valueOf(Math.PI / 180)).doubleValue()) *
            Math.sin(dLon.doubleValue() / 2) * Math.sin(dLon.doubleValue() / 2));

    BigDecimal c = new BigDecimal(2 * Math.atan2(Math.sqrt(a.doubleValue()), Math.sqrt(1 - a.doubleValue())));

    // 计算距离
    BigDecimal distance = EARTH_RADIUS.multiply(c);

    // 将距离精确到小数点后两位
    return distance.setScale(2, RoundingMode.HALF_UP);
  }
}

